﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotSpatial.Topology;
using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;

namespace HAGISV2
{
    /// <summary>
    /// 框框点线层
    /// </summary>
    [Serializable]
    public class ConceptFrameLayer:Layer
    {
        public ConceptFrameLayer(string id,RectangleFrame rectangleFrame)
            : base(id)
        {
            _rectFrame = rectangleFrame;

            this._isSelectable = true;
            this.BuildDataset();


            FillFeatures();

        }




        #region 字段及属性

        [NonSerialized]
        bool _isPointLayerSelectedAndShow;
        /// <summary>
        /// 便于 MapFunction操作
        /// </summary>
        public bool IsPointLayerSelectedAndShow
        {
            get { return _isPointLayerSelectedAndShow; }
            set { _isPointLayerSelectedAndShow = value; }
        }

        RectangleFrame _rectFrame;
        /// <summary>
        /// 框框点信息
        /// </summary>
        public RectangleFrame RectFrame
        {
            get { return _rectFrame; }
            set 
            {
                if (value == null) return;
                _rectFrame = value;
                OnRectFrameChanged();
            }
        }


        /// <summary>
        /// 四条边左上右下
        /// </summary>
        public List<LineSegment> LeftTopRihgtBotLine
        {
            get 
            {
                return  GetLeftTopRightBotLineSegment(); 
            }
        }
        List<LineSegment> GetLeftTopRightBotLineSegment()
        {
            List<LineSegment> lss = new List<LineSegment>();
            if (_rectFrame == null) throw new Exception("rectFrame参数在此不应为空");
            if (_rectFrame.FourBounderCoordinates == null && !_rectFrame.ReGenerate()) throw new Exception("rectFrame内部生成失败");

            lss.Add(new LineSegment(_rectFrame.FourBounderCoordinates[0],_rectFrame.FourBounderCoordinates[1]));
            lss.Add(new LineSegment(_rectFrame.FourBounderCoordinates[1], _rectFrame.FourBounderCoordinates[2]));
            lss.Add(new LineSegment(_rectFrame.FourBounderCoordinates[2], _rectFrame.FourBounderCoordinates[3]));
            lss.Add(new LineSegment(_rectFrame.FourBounderCoordinates[3], _rectFrame.FourBounderCoordinates[0]));

            return lss;
        }


        [NonSerialized]
        protected FeatureSet _ptFeatureSet;
        [NonSerialized]
        protected FeatureSet _lnFeatureSet;



        [NonSerialized]
        protected MapLineLayer _lnLayer;

        public MapLineLayer LnLayer
        {
            get { return _lnLayer; }

        }


        [NonSerialized]
        protected MapPointLayer _ptLayer;

        public MapPointLayer PtLayer
        {
            get { return _ptLayer; }

        }

        public string LayerFileNamePt
        {
            get { return this.DefaultManager.layerPath + this.Id + "_pt.shp"; }
        }

        public string LayerFileNameLn
        {
            get { return this.DefaultManager.layerPath + this.Id + "_ln.shp"; }
        }


        #endregion





        #region 保护及私有方法

        void FillFeatures()
        {
            if (_ptFeatureSet.Features.Count > 0) _ptFeatureSet.Features.Clear();
            if (_lnFeatureSet.Features.Count > 0) _lnFeatureSet.Features.Clear();

            _ptFeatureSet.Features.Add(_rectFrame.FourBounderCoordinates);
            _ptFeatureSet.Features.Add(_rectFrame.FourMidCoordinates);
            _ptFeatureSet.Features.Add((_rectFrame.FourBounderCoordinates[3] - _rectFrame.FourBounderCoordinates[0]) * 1.08 + _rectFrame.FourBounderCoordinates[0]);

            List<Coordinate> helperList = new List<Coordinate>();
            helperList.AddRange(_rectFrame.FourBounderCoordinates);
            helperList.Add(_rectFrame.FourBounderCoordinates[0]);

            _lnFeatureSet.Features.Add(new LinearRing(helperList));
        }

        protected override void OnSetVisible()
        {
            if (!this.IsLoaded)
            {
                return;

            }
            if (this._visiable == true && this._viewMode == FMAPVIEW.NORMAL)
            {
                this._ptLayer.IsVisible = true;
                this._lnLayer.IsVisible = true;
            }
            else
            {
                this._ptLayer.IsVisible = false;
                this._lnLayer.IsVisible = false;
            }
        }

        void OnRectFrameChanged()
        {
            _rectFrame.ReGenerate();
            this.Redraw();
        }

        protected virtual void BuildDataset()
        {
            _ptFeatureSet = new FeatureSet(FeatureType.Point);
            
            _lnFeatureSet = new FeatureSet(FeatureType.Line);


        }

        protected void LoadFeatures()
        {
            this._ptFeatureSet.InvalidateVertices();
            this._ptFeatureSet.UpdateExtent();

            this._lnFeatureSet.InvalidateVertices();
            this._lnFeatureSet.UpdateExtent();

            
        }

        protected void SaveFeatures()
        {

        }


        //=============================================================================================
        protected override void OnViewModeChanged()
        {
            this.OnSetVisible();
            //this.Redraw();
        }


        #endregion

        #region 公共方法

        public override Extent GetLayerExtent()
        {
            if (!this.IsLoaded||this._viewMode!= FMAPVIEW.NORMAL)
            {
                return null;
            }

            _ptLayer.DataSet.UpdateExtent();
            return _ptLayer.Extent;
        }

        public override int MapLayerCount
        {
            get
            {
                return 2;
            }
        }

        public override void Render()
        {
            Map map = this.DefaultManager.CurrentMap;
            
            _lnLayer = (MapLineLayer)map.Layers.Add(this._lnFeatureSet);
            _ptLayer = (MapPointLayer)map.Layers.Add(this._ptFeatureSet);

            if (this._mapLayerIndex != -1)
            {
                _lnLayer.LockDispose();
                _ptLayer.LockDispose();

                map.Layers.Remove(_ptLayer);
                map.Layers.Remove(_lnLayer);

                map.Layers.Insert(this._mapLayerIndex, _ptLayer);
                map.Layers.Insert(this._mapLayerIndex, _lnLayer);

                _lnLayer.UnlockDispose();
                _ptLayer.UnlockDispose();

                this._mapLayerIndex = -1;
            }


            _lnLayer.SelectionEnabled = false;
            _ptLayer.SelectionEnabled = false;

            _lnLayer.Symbolizer = new LineSymbolizer(System.Drawing.Color.ForestGreen, 3);
            _lnLayer.SelectionSymbolizer = new LineSymbolizer(System.Drawing.Color.ForestGreen, 3);

            _ptLayer.Symbolizer = new PointSymbolizer(System.Drawing.Color.Transparent, DotSpatial.Symbology.PointShape.Ellipse, 10);
            _ptLayer.SelectionSymbolizer = new PointSymbolizer(System.Drawing.Color.DarkBlue, DotSpatial.Symbology.PointShape.Ellipse, 10);

            //_ptLayer.SelectionSymbolizer.Symbols[_ptLayer.SelectionSymbolizer.Symbols.Count - 1] = new Symbol(SymbolType.Simple);
            this._isLoaded = true;
            OnSetVisible();
        }

        public override void Redraw()
        {
            if (_ptLayer != null && _lnLayer != null)
            {
                _ptLayer.DataSet.Features.Clear();

                foreach (Coordinate item in _rectFrame.FourBounderCoordinates)
                {
                    _ptLayer.DataSet.Features.Add(item);
                }
                foreach (Coordinate item in _rectFrame.FourMidCoordinates)
                {
                    _ptLayer.DataSet.Features.Add(item);
                }
                _ptLayer.DataSet.Features.Add((_rectFrame.FourBounderCoordinates[3] - _rectFrame.FourBounderCoordinates[0]) * 1.08 + _rectFrame.FourBounderCoordinates[0]);

                List<Coordinate> helperList = new List<Coordinate>();
                helperList.AddRange(_rectFrame.FourBounderCoordinates);
                helperList.Add(_rectFrame.FourBounderCoordinates[0]);

                _lnLayer.DataSet.Features.Clear();
                _lnLayer.DataSet.Features.Add(new LinearRing(helperList));

                _ptLayer.DataSet.InitializeVertices();
                _lnLayer.DataSet.InitializeVertices();

                _ptLayer.DataSet.UpdateExtent();
                _lnLayer.DataSet.UpdateExtent();

                _ptLayer.Invalidate();
                _lnLayer.Invalidate();
            }
            else
            {
                _rectFrame.ReGenerate();
                FillFeatures();
            }
        }

        public override void StopRender()
        {

            Map map = this.DefaultManager.CurrentMap;

            map.Layers.Remove(this._ptLayer);
            map.Layers.Remove(this._lnLayer);





            this._isLoaded = false;


        }


        public override bool OpenLayer()
        {
            this.BuildDataset();

            this.Update();

            this.Render();
            this.DefaultManager.CurrentMap.Invalidate();


            return true;
        }

        public override bool SaveLayer()
        {

            this.SaveFeatures();

            return base.SaveLayer();

        }


        public override void Select(IEnvelope tolerant, IEnvelope strict, SelectionMode selectionMode)
        {

            //IEnvelope env;

            //this._ptLayer.Select(tolerant, strict, selectionMode, out env);
            //this._lnLayer.Select(tolerant, strict, selectionMode, out env);
            

            //List<IFeature> selectedFeatures = new List<IFeature>();

            //selectedFeatures.AddRange(this._ptLayer.Selection.ToFeatureList());
            //selectedFeatures.AddRange(this._lnLayer.Selection.ToFeatureList());



        }

        //public void SelectPtLayer()
        //{

        //}


        public override void ClearSelection()
        {
            _isPointLayerSelectedAndShow = false;
            if (_ptLayer.Selection.Count > 0)
            {
                this._ptLayer.Selection.Clear();
            }
            if (_lnLayer.Selection.Count > 0)
            {
                this._lnLayer.Selection.Clear();
            }
        }




        #endregion

    }
}
